package org.skydiveapplibrary.ui;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

public class DrawingView extends View
{
	private Bitmap  backgroundBitmap;
    private Canvas  backgroundCanvas;
    private Path    mPath;
    private Paint   mBitmapPaint;
    private Paint   drawingPaint;
	private boolean bitmapClear;
	private boolean bitmapChanged;
	
    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 1;

	public DrawingView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
	    initView();
	}
	
	public DrawingView(Context context, AttributeSet attrs, int defStyle)
	{
		 super(context, attrs, defStyle);
		 initView();
	} 
		
	private void initView()
	{
		setWillNotDraw(false);
		bitmapClear = true;
		bitmapChanged = false;
		
		mPath = new Path();
		mBitmapPaint = new Paint(Paint.DITHER_FLAG);
		
		Display display = ((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

		@SuppressWarnings("deprecation")
		int width = display.getWidth();
		@SuppressWarnings("deprecation")
		int height = display.getHeight();
		
		backgroundBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
		backgroundCanvas = new Canvas(backgroundBitmap);
		
		drawingPaint = new Paint();
		drawingPaint.setAntiAlias(true);
		drawingPaint.setDither(true);
		drawingPaint.setColor(Color.BLACK);
		drawingPaint.setStyle(Paint.Style.STROKE);
		drawingPaint.setStrokeJoin(Paint.Join.ROUND);
		drawingPaint.setStrokeCap(Paint.Cap.ROUND);
		drawingPaint.setStrokeWidth(5);
	}

	public void drawBitmap(Bitmap bitmap)
	{
		bitmapClear = false;
		bitmapChanged = false;
		// scale to size
		Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		Rect dst = new Rect(0, 0, backgroundBitmap.getWidth(), backgroundBitmap.getHeight());
		// draw bitmap
		backgroundCanvas.drawBitmap(bitmap, src, dst, null);
	}
	
	public boolean isBitmapChanged()
	{
		return bitmapChanged;
	}
	
	public byte[] getImageData()
	{
		// if clear, return null
		if (bitmapClear)
			return null;
		
		byte[] data = null;
		try
		{
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			backgroundBitmap.compress(CompressFormat.PNG, 0, bos);
			data = bos.toByteArray();
			bos.close();
		}
		catch (IOException ex)
		{
			// error
			Log.e(DrawingView.class.getName(), ex.getMessage());
		}
		
		return data;
	}
	
	public void clear()
	{
		bitmapClear = true;
		bitmapChanged = true;
		// clear canvas
		clearBackgroundCanvas();
		// redraw
		invalidate();
	}
	
    @Override
    protected void onDraw(Canvas canvas) 
    {
    	bitmapChanged = true;
    	bitmapClear = false;
    	
        canvas.drawColor(Color.WHITE);

        canvas.drawBitmap(backgroundBitmap, 0, 0, mBitmapPaint);

        canvas.drawPath(mPath, drawingPaint);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        float x = event.getX();
        float y = event.getY();
        
		bitmapClear = false;
		bitmapChanged = true;

        switch (event.getAction()) 
        {
            case MotionEvent.ACTION_DOWN:
                touch_start(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touch_up();
                invalidate();
                break;
        }
        return true;
    }

    private void touch_start(float x, float y) 
    {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }
    private void touch_move(float x, float y) 
    {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) 
        {
            mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
            mX = x;
            mY = y;
        }
    }
    private void touch_up() 
    {
        mPath.lineTo(mX, mY);
        // commit the path to our offscreen
        backgroundCanvas.drawPath(mPath, drawingPaint);
        // kill this so we don't double draw
        mPath.reset();
    }

	private void clearBackgroundCanvas()
	{
		backgroundCanvas.drawColor(0, Mode.CLEAR);
	}
}
